유사도 (Similarity)란
유사도(Similarity)는 두 데이터 객체가 얼마나 서로 비슷한지를 나타내는 척도입니다.
0과 1 사이의 값으로 표현되며, 값이 1에 가까울수록 두 데이터가 매우 비슷하다는 의미입니다.
유사도는 추천 시스템, 텍스트 마이닝, 이미지 검색 등 다양한 분야에서 사용됩니다.
대표적인 유사도 측정 방법
1. 코사인 유사도 (Cosine Similarity)
코사인 유사도는 두 벡터 사이의 방향이 얼마나 비슷한지를 측정합니다.
벡터의 크기보다는 방향에 초점을 맞추기 때문에, 주로 문서나 텍스트 데이터의 유사도를 계산하는 데 널리 사용됩니다.
핵심 개념
- 두 벡터가 이루는 각도의 코사인 값.
- 두 벡터의 방향이 완전히 같으면 1, 90°의 각을 이루면 0, 완전히 반대 방향이면 -1의 값을 가집니다.
계산
두 벡터의 내적을 각각의 크기(노름)의 곱으로 나눕니다.
예시
"나는 사과가 좋다"와 "나는 사과가 정말 좋다"라는 두 문장은 단어의 개수(벡터의 크기)는 다르지만,
'사과'와 '좋다'는 방향성이 같으므로 코사인 유사도가 높게 나옵니다.
2. 자카드 유사도 (Jaccard Similarity)
자카드 유사도는 두 집합이 얼마나 많은 요소를 공유하는지를 측정합니다.
주로 집합 데이터 간의 유사성을 비교하는 데 사용되며, 결과는 0과 1 사이의 값을 가집니다.
핵심 개념
두 집합의 교집합(공통된 원소)의 크기를 합집합(전체 원소)의 크기로 나눈 값입니다.
예시
- A의 장바구니: {사과, 바나나, 우유}
- B의 장바구니: {사과, 빵, 우유}
- 교집합(공통 상품): {사과, 우유} (2개)
- 합집합(전체 상품): {사과, 바나나, 우유, 빵} (4개)
- 자카드 유사도 = 2 / 4 = 0.5
3. 유클리드 거리 (Euclidean Distance)와 유사도
유클리드 거리는 두 점 사이의 직선 거리를 측정하는 가장 일반적인 방법입니다.
거리가 가까울수록 두 데이터가 비슷하다고 판단할 수 있으므로, 유사도를 계산하는 데 활용될 수 있습니다.
핵심 개념
- 좌표 공간상에서 두 점을 잇는 가장 짧은 거리.
- 각 차원별 차이의 제곱을 모두 더한 후 제곱근을 씌웁니다.
계산
유사도로의 변환 및 예시
- 유클리드 거리는 값이 작을수록 유사하므로, 보통 `1 / (1 + 거리)` 와 같은 방식으로 변환하여 0과 1 사이의 유사도 값으로 사용합니다. 거리가 0이면 유사도는 1이 됩니다.
- 사용자의 평점 데이터를 좌표평면의 점으로 보고, 두 사용자 간의 거리를 계산하여 취향이 비슷한 사용자를 찾는 데 사용할 수 있습니다.
문장 유사도 분석: 실제 계산 예시
1단계
문장을 벡터로 변환 (Bag-of-Words)
먼저 각 문장에 특정 단어가 몇 번 나타나는지를 세어 숫자 벡터로 만듭니다. 여기서 단어 주머니(Vocabulary)는 {love, apple, delicious, ...} 라고 가정합니다.
| 문장 | 내용 | 벡터 (Vector) | 크기 (Magnitude) |
|---|---|---|---|
| 1 | I love apple. | [1, 1, 0, ...] | $$ \sqrt{1^2 + 1^2} = \sqrt{2} $$ |
| 2 | Apple is delicious which I love too. | [1, 1, 1, ...] | $$ \sqrt{1^2 + 1^2 + 1^2} = \sqrt{3} $$ |
| 3 | I want a delicious food, but not an apple. | [0, 1, 1, ...] | $$ \sqrt{0^2 + 1^2 + 1^2} = \sqrt{2} $$ |
| 4 | Deep learning is difficult. | [0, 0, 0, ...] | $$ \sqrt{0} = 0 $$ |
2단계
코사인 유사도 계산
벡터화된 문장들을 바탕으로 코사인 유사도 공식을 적용하여 실제 유사도 점수를 계산합니다.
[1, 2]: 1번 문장 vs 2번 문장
- 분자 (내적)
(1 * 1) + (1 * 1) + (0 * 1) = 2 - 분모 (크기의 곱)
$$ \sqrt{2} \times \sqrt{3} = \sqrt{6} $$
➡️ 결론 점수가 1에 가까워 매우 유사하다고 판단합니다.
[2, 4]: 2번 문장 vs 4번 문장
- 분자 (내적)
(1 * 0) + (1 * 0) + (1 * 0) = 0 - 분모 (크기의 곱)
$$ \sqrt{3} \times 0 = 0 $$
➡️ 결론 점수가 0이므로 전혀 유사하지 않다고 판단합니다.
[1, 3]: 1번 문장 vs 3번 문장
- 분자 (내적)
(1 * 0) + (1 * 1) + (0 * 1) = 1 - 분모 (크기의 곱)
$$ \sqrt{2} \times \sqrt{2} = 2 $$
➡️ 결론 'apple' 단어만 겹쳐 0.5의 유사도를 가집니다. 어느 정도 관련은 있지만, [1, 2] 경우보다는 유사도가 낮다고 해석할 수 있습니다.
또 다른 거리 척도
레벤슈타인 거리
4. 레벤슈타인 거리 (Levenshtein Distance)
레벤슈타인 거리는 두 문자열(단어 또는 문장)이 얼마나 다른지를 측정하는 '편집 거리(Edit Distance)'의 한 종류입니다.
이 값은 유사도가 아니라 '거리'이므로, 값이 작을수록 두 문자열이 더 비슷하다는 의미입니다.
핵심 개념
- 문자열 A를 문자열 B로 바꾸기 위해 필요한 최소한의 편집 횟수를 계산합니다.
- 세 가지 연산
- 삽입 (Insertion)
문자를 추가하는 연산 - 삭제 (Deletion)
문자를 제거하는 연산 - 변경 (Substitution)
한 문자를 다른 문자로 바꾸는 연산
- 삽입 (Insertion)
"가나다"와 "가다라" 사이의 거리 계산 예시
- "가나다"에서 '나'를 '다'로 변경합니다. → "가다다" (비용: 1)
- "가다다"에서 마지막 '다'를 '라'로 변경합니다. → "가다라" (비용: 1)
➡️ 결론 총 2번의 '변경' 연산이 필요했으므로, "가나다"와 "가다라"의 레벤슈타인 거리는 2입니다.
어디에 사용될까요?
- 철자 교정기
'aple'을 입력했을 때 거리가 1인 'apple'을 추천합니다. - 검색 엔진
오타를 입력해도 "이것을 찾으셨나요?"라며 비슷한 단어를 제안합니다. - DNA 염기서열 분석
두 DNA 시퀀스가 얼마나 유사한지 비교하는 데 사용됩니다.